#pragma once
#include "VertexIndexSupport.h"
#include <map>
#include <hash_map>

using namespace std;
/**
* This class provides the functors for the hash_map implementation
* @author Koen Samyn
*/
class IndexTranslatorHasher :public stdext::hash_compare <VertexIndexSupport>
{
public:
	/**
	* hash function, sum of all the indices.
	*/
	size_t operator() (const VertexIndexSupport& vis) const
	{
		return vis.hash();
	}

	/**
	* 
	* @param s1 The first VertexIndexSupport object
	* @param s2 The second VertexIndexSupport object
	* @return true if the first VertexIndexSupport object comes before the second VertexIndexSupport object.
	*/
	bool operator() (const VertexIndexSupport& vis1, const VertexIndexSupport& vis2) const
	{
		return vis1 < vis2;
	}
};

typedef stdext::hash_map<VertexIndexSupport, int, IndexTranslatorHasher> VISHASH;



/**
* The index translator maintains the translation between the 
* original vertex index as defined in the source 3D content file 
* and the related mesh index for the vertexbuffer in the 3D application. 
*/
class IndexTranslator
{
public:
	/**
	* Creates a new IndexTranslator object
	*/
	IndexTranslator();
	/**
	* Destroys the IndexTranslator object.
	*/
	virtual ~IndexTranslator();
	/**
	* Adds a vertex index to the map of translated indices.
	* @param vis the indices as defined in the original 3D content file.
	* @param meshVertexIndex the index to use in the resulting vertexbuffer.
	*/
	void AddVertexIndex(VertexIndexSupport& vis,int meshVertexIndex);
	/**
	* Checsk if a VertexIndexSupport is allready present in the map.
	* @return true if the key is present in the map, false otherwise.
	*/
	bool ContainsAbsVertexIndex(VertexIndexSupport vis);
	/**
	* Returns the mesh index for the given VertexIndexSupport key.
	* @param index the original indices in the 3D content file.
	* @return the index in the resulting vertex buffer.
	*/
	int GetMeshIndex(VertexIndexSupport index);
	/**
	* Gets the mesh index if it exists.
	* @param index the vertexindexsupport that defines a vertex.
	* @param meshIndex out parameter for the mesh index.
	*/
	bool GetMeshIndex(VertexIndexSupport& index, int* meshIndex);

private:
	/**
	* The map that relates indices in a 3D content file to an index in a vertexbuffer.
	*/
	VISHASH m_translationMap;
};

/**
* Support for smoothing groups.
*/
class SmoothingGroup
{
public:
	/**
	* Creates a new SmoothingGroup object.
	*/
	SmoothingGroup(void);
	/**
	* Deletes the SmoothingGroup object.
	*/
	~SmoothingGroup(void);
	/**
	* Adds a vertex to a specific smoothing group.
	*/
	void AddVertexIndex(int smoothingGroup, VertexIndexSupport& vis,int meshVertexIndex);
	bool ContainsAbsVertexIndex(int smoothingGroup, VertexIndexSupport vis);
	int GetMeshIndex(int smoothingGroup, VertexIndexSupport& vis);
	bool GetMeshIndex(int smoothingGroup, VertexIndexSupport& vis, int* meshIndex);
private:
	map<int,IndexTranslator*> m_SmoothingGroupMap;
};
